#include "SvrMgr.h"
#include "ShmMgr.h"
#include "MainSvr.h"
#include "WorkSvr.h"
#include "BufMgr.h"

#define SERVER_PORT 9898
// 所有服务IPC发送缓冲共用共享内存128M
#define IPC_MEM_SIZE 134217728

CSvrMgr::CSvrMgr()
{
    m_ilfd = -1;
    m_pShmMgr = nullptr;
    m_pMainSvr = nullptr;
    m_pIpcBufMgr = nullptr;
}

CSvrMgr::~CSvrMgr()
{
    Destroy();
}

void *CSvrMgr::operator new(size_t sz)
{
    void *ptr = nullptr;
    CSvrMemBlock *smb = CSvrMemBlock::GetInstance();

    if (nullptr != smb)
        ptr = smb->Alloc(sz);

    return ptr;
}

void CSvrMgr::operator delete(void *ptr)
{
    CSvrMemBlock *smb = CSvrMemBlock::GetInstance();

    if (nullptr != smb)
        smb->Destroy();
}

CSvrMgr *CSvrMgr::Create(int nCore)
{
    CSvrMgr *pSvrMgr = nullptr;
    int iSize = sizeof(CSvrMemBlock) + sizeof(CSvrMgr) + sizeof(CShmMgr) + sizeof(CMainSvr) + nCore * (sizeof(SvrNode) /* + sizeof(CWorkSvr)*/);
    CSvrMemBlock *smb = CSvrMemBlock::Create(iSize);

    if (nullptr == smb)
        return nullptr;

    pSvrMgr = CSvrMgr::GetInstance();

    if (nullptr == pSvrMgr)
        smb->Destroy();

    return pSvrMgr;
}

bool CSvrMgr::Init()
{
    uint64_t nSize = 0;
    void *pShmPtr = nullptr;
    CShmBlock *pIpcShm = nullptr;

    // 创建共享内存管理
    m_pShmMgr = CShmMgr::GetInstance();

    if (nullptr == m_pShmMgr)
        return false;

    // 创建IPC所需的共享内存块
    pIpcShm = m_pShmMgr->CreateShmBlock(IPC_MEM_SIZE);

    if (nullptr == pIpcShm)
    {
        Destroy();
        return false;
    }

    nSize = pIpcShm->GetUnuseLength();
    pShmPtr = pIpcShm->Alloc(nSize);
    m_pIpcBufMgr = CBufMgr<CSpinLock>::Create(pShmPtr, nSize);

    if (nullptr == m_pIpcBufMgr)
    {
        Destroy();
        return false;
    }

    if (!m_pIpcBufMgr->Init())
    {
        Destroy();
        return false;
    }

    m_ilfd = CServer::BindAndListen(SERVER_PORT);

    if (-1 == m_ilfd)
    {
        Destroy();
        return false;
    }

    return true;
}

void CSvrMgr::Destroy()
{
    if (-1 != m_ilfd)
    {
        close(m_ilfd);
        m_ilfd = -1;
    }

    if (nullptr != m_pMainSvr)
    {
        delete m_pMainSvr;
        m_pMainSvr = nullptr;
    }

    m_lstWorkSvr.Destroy();

    if (nullptr != m_pIpcBufMgr)
    {
        m_pIpcBufMgr->Destroy();
        m_pIpcBufMgr = nullptr;
    }

    if (nullptr != m_pShmMgr)
    {
        // 所有分配的共享内存块一并销毁
        delete m_pShmMgr;
        m_pShmMgr = nullptr;
    }
}

CMainSvr *CSvrMgr::CreateMainSvr()
{
    if (nullptr != m_pMainSvr)
        return m_pMainSvr;

    m_pMainSvr = new CMainSvr();

    return m_pMainSvr;
}

CWorkSvr *CSvrMgr::CreateWorkSvr()
{
    SvrNode *pNode = (SvrNode *)m_lstWorkSvr.NewNode();

    if (nullptr == pNode)
        return nullptr;

    if (!m_lstWorkSvr.PushBack(pNode))
    {
        m_lstWorkSvr.DeleteNode(pNode);
        return nullptr;
    }

    return (CWorkSvr *)pNode;
}

void CSvrMgr::DestroyMainSvr(CMainSvr *pMainSvr)
{
    if ((nullptr == pMainSvr) || (pMainSvr != m_pMainSvr))
    {
        printf("Error DestroyMainSvr:\tfile=%s\tline=%d\n", __FILE__, __LINE__);
        return;
    }

    delete pMainSvr;
    m_pMainSvr = nullptr;
}

void CSvrMgr::DestroyWorkSvr(CWorkSvr *pWorkSvr)
{
    if (nullptr == pWorkSvr)
    {
        printf("Error DestroyWorkSvr:\tfile=%s\tline=%d\n", __FILE__, __LINE__);
        return;
    }

    m_lstWorkSvr.Remove((SvrNode *)pWorkSvr);
    m_lstWorkSvr.DeleteNode((SvrNode *)pWorkSvr);
}

// 后续再优化算法
CWorkSvr *CSvrMgr::GetAcceptServer()
{
    SvrNode *pMinSvr = nullptr;
    SvrNode *pNode = (SvrNode *)m_lstWorkSvr.GetHeader();

    while (nullptr != pNode)
    {
        if (nullptr == pMinSvr)
        {
            pMinSvr = pNode;
        }
        else if (pMinSvr->GetClientCount() > pNode->GetClientCount())
        {
            pMinSvr = pNode;
        }

        pNode = (SvrNode *)pNode->Next();
    }

    return (CWorkSvr *)pMinSvr;
}